﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using System.Web.Security;
using System.Configuration;
using DevExpress.Web.ASPxCallback;

namespace TireService.Web.View.AdminView
{
    public partial class ManageServiceDriveTaskPreparation : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            BindCarsNeedService(Convert.ToInt32(ddlTireType.SelectedItem.Value));
        }

        /// <summary>
        /// Helper function that return list of cars that has tires changed and with a specific tires on stock
        /// </summary>
        /// <param name="TireType">TireType that must be on stock</param>
        /// <param name="db">Connection to database</param>
        /// <returns>List of Car Objects</returns>
        private static List<Car> GetCars(int TireType, TireServiceDB db)
        {
            List<Car> cars = db.GetCarsByCarStatusId((int)Shared.CarStatus.TireChanged).ToList();
            List<Car> newcars = new List<Car>();


            foreach (Car car in cars)
            {
                // Get Tireset
                int[] TireSetStatus = new int[] { (int)Shared.TireSetStatus.OnStock, (int)Shared.TireSetStatus.StockedAtCustomer, (int)Shared.TireSetStatus.AwaitsMoveToStock, (int)Shared.TireSetStatus.PlacedAtCustomer };
                List<TireSet> tireset = db.GetCarTireSetByTireSetStatus(car.CarId, TireSetStatus);

                if (tireset.Count == 0)
                {
                    // Error - remove car from list
                    //cars.Remove(car);
                }
                if (tireset.Count > 1)
                {
                    // Error - remove car from list
                    //cars.Remove(car);
                }
                if (tireset.Count == 1)
                {
                    if (tireset.First().TireTypeId != TireType)
                    {
                        // Remove car since it already have the correct tires mounted
                        //cars.Remove(car);
                    }
                    else
                    {
                        newcars.Add(car);
                    }
                }
            }
            return newcars;
        }

        /// <summary>
        /// Function that bind gridview with all cars that has gotten tires changed (a specific tiretype)
        /// </summary>
        /// <param name="TireType">TireType that must be on stock</param>
        private void BindCarsNeedService(int TireType) 
        {
            try
            {
                // Instantiate datalayer 
                TireServiceDB db = new TireServiceDB();

                List<Car> cars = GetCars(TireType, db);

                gvCarList.DataSource = cars;
                gvCarList.DataBind();

                db.Dispose();

            }
            catch (Exception ex)
            {
                string error = ex.Message;
            }
        }

        /// <summary>
        /// Function that creates tasks for all cars that has tires changed
        /// </summary>
        /// <param name="TireType">TireType that must be on stock</param>
        private void CreateServiceDriveTasks(int TireType, bool SendBookingEmail, int TaskCount) 
        {
            // Instantiate datalayer and business layer
            TireServiceDB db = new TireServiceDB();
            TaskBLL taskBLL = new TaskBLL();

            // Array for servicetask log (1: CarId, 2: Action and description (Ok, Failed))
            Dictionary<int, string> servicetask_log = new Dictionary<int, string>();

            // Instantiate email service
            EmailNotificationServices emailService = new EmailNotificationServices();

            // Get UserId
            Guid UserId = new Guid(Membership.GetUser().ProviderUserKey.ToString());

            List<Car> cars = GetCars(TireType, db);

            foreach (Car car in cars.Take(TaskCount))
            {
                // Get customer
                Customer customer = db.GetCustomer(car.CustomerId);

                // Get Tireset
                int[] TireSetStatus = new int[] { (int)Shared.TireSetStatus.OnStock, (int)Shared.TireSetStatus.StockedAtCustomer, (int)Shared.TireSetStatus.AwaitsMoveToStock, (int)Shared.TireSetStatus.PlacedAtCustomer };
                List<TireSet> tireset = db.GetCarTireSetByTireSetStatus(car.CarId, TireSetStatus);

                if (tireset == null)
                {
                    // Error
                    servicetask_log.Add(car.CarId, "Opdatering kan ikke gennemføres - bil med reg.nr: " + car.RegistrationNumber + " har ingen hjulsæt der kan sættes på");
                }
                if (tireset.Count > 1)
                {
                    // Error
                    servicetask_log.Add(car.CarId, "Opdatering kan ikke gennemføres - bil med reg.nr: " + car.RegistrationNumber + " har 2 hjulsæt der kan sættes på");
                }
                if (tireset.Count == 1)
                {
                    int TireSetId = tireset.First().TireSetId;

                    if (customer.OnPrimaryAddressInPrimeTime)
                    {
                        // Customer Primary address selected
                        // Create servicedrive task
                        Task task = taskBLL.CreateTask(db,
                                                    null,
                                                    (int)Shared.TaskType.ServiceDrive,
                                                    (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                    (int)Shared.TaskTypeStatus.ServiceDrive_Created, customer.CustomerId, car.CarId,
                                                    TireSetId,
                                                    customer.Address,
                                                    customer.ZipCode,
                                                    customer.City,
                                                    customer.CountryId,
                                                    customer.CommentToAddress,
                                                    customer.SecondaryAddress,
                                                    customer.SecondaryZipCode,
                                                    customer.SecondaryCity,
                                                    customer.CountryId,
                                                    customer.CommentToSecondaryAddress,
                                                    null,
                                                    1,
                                                    UserId,
                                                    true);
                    }
                    else
                    {
                        // Customer Secondary address selected
                        // Create servicedrive task
                        Task task = taskBLL.CreateTask(db,
                                                    null,
                                                    (int)Shared.TaskType.ServiceDrive,
                                                    (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                    (int)Shared.TaskTypeStatus.ServiceDrive_Created, customer.CustomerId, car.CarId,
                                                    TireSetId,
                                                    customer.SecondaryAddress,
                                                    customer.SecondaryZipCode,
                                                    customer.SecondaryCity,
                                                    customer.CountryId,
                                                    customer.CommentToSecondaryAddress,
                                                    customer.Address,
                                                    customer.ZipCode,
                                                    customer.City,
                                                    customer.CountryId,
                                                    customer.CommentToAddress,
                                                    null,
                                                    1,
                                                    UserId,
                                                    true);
                    }

                    if (SendBookingEmail)
                    {
                        // Send email to customer with booking link
                        if (customer.UserId != null)
                        {
                            try
                            {
                                string BookingLink = string.Format(ConfigurationManager.AppSettings["Website"] + "Booking/Booking.aspx?uid={0}", customer.UserId.ToString());

                                emailService.CustomerBookingLink_SendCustomerEmail(customer.Email, customer.Name, customer.CustomerId, Membership.GetUser(), BookingLink);

                                // OK
                                servicetask_log.Add(car.CarId, "Opgave oprettet og booking link sendt på mail");
                            }
                            catch (Exception)
                            {
                                // Error
                                servicetask_log.Add(car.CarId, "Opgave oprettet, men email kunne ikke sendes for kundeid: " + customer.CustomerId.ToString());
                            }
                                
                        }
                        else
                        {
                            // Error
                            servicetask_log.Add(car.CarId, "Opgave oprettet, men email kunne ikke sendes for kundeid: " + customer.CustomerId.ToString());
                        }
                    }
                    else
                    {
                        // OK
                        servicetask_log.Add(car.CarId, "Opgave oprettet");
                    }

                    // Update car with new status
                    car.CarStatusId = (int)Shared.CarStatus.AwaitsTireChangePlanning;
                }
                    
            }

            db.SubmitChanges();

            //BindCarsNeedService(TireType);

            // Return log on task creation to finance email
            string logHTML = "<b>Log på oprettelse af service kørsler</b><br><table><tr><td>Bil Id</td><td>Status og handling</td></tr>";
            foreach (KeyValuePair<int, string> log in servicetask_log)
            {
                logHTML += "<tr><td>" + log.Key.ToString() + "</td><td>" + log.Value + "</td></tr>";
            }
            logHTML += "</table>";

            string Subject = "Sæson forberedelse - Service kørsler oprettet";
            emailService.SendFinanceInternalEmailNotification(Subject, logHTML);

            db.Dispose();
        }

        /// <summary>
        /// Postback function that updates gridview with carlist
        /// </summary>
        protected void gvCarList_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            BindCarsNeedService(Convert.ToInt32(e.Parameters));
        }

        protected void callCreateServiceDriveTasks_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                TireServiceDB db = new TireServiceDB();

                // Get input (0: TireType, 1: Sendbookinglink, 2: TaskCount)
                string[] param = e.Parameter.Split('|');

                CreateServiceDriveTasks(Convert.ToInt32(param[0]), Convert.ToBoolean(param[1]), Convert.ToInt32(param[2]));
            }
            catch (Exception ex)
            {
                string error = ex.Message;

            }
        }
    }
}